package com.ruoyi.combat.config;


import cn.hutool.json.JSONUtil;
import com.ruoyi.combat.domain.neo4j.IpNode;
import com.ruoyi.combat.domain.neo4j.IpcNode;
import com.ruoyi.combat.domain.neo4j.OrgNode;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.*;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Path;
import org.neo4j.driver.types.Relationship;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class Neo4jConfig {

    private Session session;

    private Session session1;
    @Value("${spring.neo4j.uri}")
    private String uri;
    @Value("${spring.neo4j.authentication.username}")
    private String user;
    @Value("${spring.neo4j.authentication.password}")
    private String password;
    @Value("${spring.data.neo4j.database}")
    private String databaseName;
    @Value("${spring.data.neo4j.database1}")
    private String databaseName1;


    public void getSession() {
        log.info("databaseName:" + databaseName);
        Driver driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
        Session session = driver.session(SessionConfig.forDatabase(databaseName));
        this.session = session;
    }

    public void getSession1() {
        log.info("databaseName:" + databaseName1);
        Driver driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
        Session session = driver.session(SessionConfig.forDatabase(databaseName1));
        this.session1 = session;
    }


    public Result run(String cypher) {
        if (session == null || !session.isOpen()) {
            getSession();
        }
        try {
            Result run = session.run(cypher);
            return run;
        } finally {
//            session.close();
        }
    }

    public Result run(String cypher, String type) {
        if ("1".equals(type)) {
            if (session == null || !session.isOpen()) {
                getSession();
            }
            log.info("databaseName:" + databaseName);
            log.info("cypher:{}", cypher);
            try {
                Result run = session.run(cypher);

                return run;
            } finally {
//                session.close();
            }
        } else {
            if (session1 == null || !session1.isOpen()) {
                getSession1();
            }
            log.info("databaseName:" + databaseName1);
            log.info("cypher:{}", cypher);
            try {
                Result run = session1.run(cypher);

                return run;
            } finally {
//                session1.close();
            }
        }
    }


    public static void main(String[] args) {
        // 连接URI格式: "neo4j://<hostname>:<bolt-port>"
        String uri = "bolt://120.210.93.157:62034";
        String user = "neo4j";
        String password = "qwe123!@#";

        try (Driver driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password))) {
            // 验证连接
            try (Session session = driver.session(SessionConfig.forDatabase("aga"))) {
                String cql = "MATCH (start_ip:Ip {Ip: '210.45.212.212'})-[:BELONGS_TO]->(ipc:IpC) MATCH (ipc)<-[:BELONGS_TO]-(landmark_ip:Ip) WHERE landmark_ip.landmark_node = 1 MATCH path = (landmark_ip)<-[*1..3]-(o:Org) RETURN start_ip, ipc, landmark_ip, o,[node IN nodes(path) | node] as all_nodes_in_path, [rel IN relationships(path) | rel] as all_relationships_in_path, length(path) as path_length";
                cql = "MATCH (n)-[r]->(m) RETURN n,r,m";
                Result run = session.run(cql);
                List<Record> list = run.list();
                List<Map> listdata = new ArrayList<>();
                list.forEach(record -> {
                    List<String> keys = record.keys();
                    Map<String, Object> data = new HashMap<>();
                    keys.forEach(key -> {
                        if ("n".equals(key)) {
                            org.neo4j.driver.Value value = record.get(key);
                            Map map = new HashMap();
                            map.put("id", value.asNode().id());
                            map.put("labels", value.asNode().labels());
                            map.put("value", value.asNode().asMap());
                            data.put(key, map);
                        } else if ("r".equals(key)) {
                            Relationship relationship = record.get(key).asRelationship();
                            Map map = new HashMap();
                                map.put("type", relationship.type());
                                map.put("start", relationship.startNodeId());
                                map.put("end", relationship.endNodeId());
                                map.put("value", relationship.asMap());
                                map.put("id", relationship.id());
                            data.put(key, map);
                        } else if ("m".equals(key)) {
                            org.neo4j.driver.Value value = record.get(key);
                            Map map = new HashMap();
                            map.put("id", value.asNode().id());
                            map.put("labels", value.asNode().labels());
                            map.put("value", value.asNode().asMap());
                            data.put(key, map);
                        }
                    });
                    listdata.add(data);
                });
                System.out.println(JSONUtil.toJsonStr(listdata));

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
